package com.ivan.toolkit.swing;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Insets;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

/**
 * <B>IvanTextField</B>
 * <P>Support text show when no text input
 * <P>Support text input verify
 * @author lingdm
 *
 */
public class PromptTextField extends JTextField implements DocumentListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3350528820639464397L;
	
	/**
	 * Label to show when no text
	 */
	private JLabel nullLabel = null;
	
	/**
	 * 
	 */
	private boolean verified = true;

	
	/**
	 * Construct	
	 */
	public PromptTextField() {
		super();
		this.getDocument().addDocumentListener(this);
	}


	/**
	 * Get label showed when no text inputed
	 */
	public JLabel getNullLabel() {
		if(this.nullLabel == null) {
			this.nullLabel = new JLabel();
			this.nullLabel.setForeground(Color.LIGHT_GRAY);
		}
		return this.nullLabel;
	}

	/**
	 * check inputed text is valid
	 */
	public boolean isVerified() {
		return this.verified;
	}

	@Override
	protected void paintComponent(Graphics g) {
		
		// draw default
		super.paintComponent(g);
		
		if(this.getText().isEmpty() && !this.isFocusOwner()) {
			Insets insets = this.getInsets();
			SwingUtilities.paintComponent(
					g, 
					getNullLabel(), 
					this, 
					insets.left, 
					insets.top,
					this.getWidth() - insets.left - insets.right, 
					this.getHeight() - insets.top - insets.bottom);	
		}
		
	}

	@Override
	public void insertUpdate(DocumentEvent e) {
		doVerify();
	}

	@Override
	public void removeUpdate(DocumentEvent e) {
		doVerify();
	}

	@Override
	public void changedUpdate(DocumentEvent e) {
		doVerify();
	}
	
	/**
	 * Internal verify logic
	 */
	private void doVerify() {
		
		boolean v;
		
		if(this.getText().isEmpty()) {
			v = true;
		} else {
			v = verify();
		}
		
		if(v != verified) {
			verified = v;
			onVerifyChanged();
		}
		
	}
	
	/**
	 * verify function to be override 
	 */
	protected boolean verify() {
		return true;
	}
	
	/**
	 * called when verify state changed
	 */
	protected void onVerifyChanged() {
		if(this.isVerified()) {
			this.setBackground(Color.WHITE);
		} else {
			this.setBackground(new Color(255, 224, 224));
		}
	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					JFrame frame = new JFrame();
					frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
					frame.setBounds(100, 100, 450, 300);
					JPanel contentPane = new JPanel();
					contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
					frame.setContentPane(contentPane);
					contentPane.setLayout(null);
					{
						PromptTextField textField = new PromptTextField() {

							private static final long serialVersionUID = -7107820154405364679L;

							@Override
							protected boolean verify() {
								return (this.getText().length() < 8);
							}
							
						};
						textField.setBounds(46, 62, 343, 21);
						contentPane.add(textField);
						textField.setColumns(10);
						textField.getNullLabel().setText("hello");
						
						//textField.getDocument().addDocumentListener(this);
					}
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

}
